package com.xiaoq.distribution.repository.impl;

import com.mongodb.DuplicateKeyException;
import com.mongodb.WriteConcern;
import com.xiaoq.distribution.entity.TicketOrderItemEntity;
import com.xiaoq.distribution.repository.ITicketOrderItemRepository;
import com.xiaoq.vo.PagingVo;
import org.apache.commons.lang3.StringUtils;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.InsertOptions;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.mongodb.morphia.query.UpdateResults;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;

/**
 * Created by chenjh on 2018/5/31.
 */
@Repository
public class TicketOrderItemRepositoryImpl implements ITicketOrderItemRepository {

    @Autowired
    private Datastore datastore;

    @Override
    public boolean save(TicketOrderItemEntity ticketOrderItemEntity) {
        if (ticketOrderItemEntity != null && StringUtils.isNotBlank(ticketOrderItemEntity.getId())){
            InsertOptions insertOptions = new InsertOptions();
            insertOptions.writeConcern(WriteConcern.W2);

            try {
                datastore.save(ticketOrderItemEntity, insertOptions);
            }catch (DuplicateKeyException e){
                throw new DuplicateKeyException(e.getResponse(), e.getServerAddress(), e.getWriteConcernResult());
            }

            return true;
        }
        return false;
    }

    @Override
    public boolean updateById(TicketOrderItemEntity ticketOrderItemEntity) {
        if (ticketOrderItemEntity == null && StringUtils.isBlank(ticketOrderItemEntity.getId())){
            return false;
        }
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class).filter("_id", ticketOrderItemEntity.getId());
        UpdateOperations<TicketOrderItemEntity> update = datastore.createUpdateOperations(TicketOrderItemEntity.class);
        update.set("updatedAt", System.currentTimeMillis());

        if(ticketOrderItemEntity.getOrderState() != null){
            update.set("orderState", ticketOrderItemEntity.getOrderState());
        }
        if(ticketOrderItemEntity.getPayState() != null){
            update.set("payState", ticketOrderItemEntity.getPayState());
        }
        if(ticketOrderItemEntity.getRefundAmount() != null){
            update.set("refundAmount", ticketOrderItemEntity.getRefundAmount());
        }
        if(ticketOrderItemEntity.getRefundTime() != null){
            update.set("refundTime", ticketOrderItemEntity.getRefundTime());
        }
        if(ticketOrderItemEntity.getSettleMoney() != null){
            update.set("settleMoney", ticketOrderItemEntity.getSettleMoney());
        }
        if(ticketOrderItemEntity.getUseTime() != null){
            update.set("useTime", ticketOrderItemEntity.getUseTime());
        }
        if(ticketOrderItemEntity.getSaleCountIndex() != null){
            update.set("saleCountIndex", ticketOrderItemEntity.getSaleCountIndex());
        }
        if(ticketOrderItemEntity.getSettleStatus() != null){
            update.set("settleStatus", ticketOrderItemEntity.getSettleStatus());
        }
        if(ticketOrderItemEntity.getSettleTime() != null){
            update.set("settleTime", ticketOrderItemEntity.getSettleTime());
        }
        if(ticketOrderItemEntity.getRefundSettleTime() != null){
            update.set("refundSettleTime", ticketOrderItemEntity.getRefundSettleTime());
        }
        if(ticketOrderItemEntity.getSettleType() != null){
            update.set("settleType", ticketOrderItemEntity.getSettleType());
        }
        if(ticketOrderItemEntity.getCreateTime() != null){
            update.set("createTime", ticketOrderItemEntity.getCreateTime());
        }
        if(ticketOrderItemEntity.getSettleUserId() != null){
            update.set("settleUserId", ticketOrderItemEntity.getSettleUserId());
        }

        datastore.update(query, update);
        return true;
    }

    @Override
    public boolean updateByOrderId(TicketOrderItemEntity ticketOrderItemEntity) {
        if (ticketOrderItemEntity == null && StringUtils.isBlank(ticketOrderItemEntity.getShopOrderId())){
            return false;
        }
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class).filter("shopOrderId", ticketOrderItemEntity.getShopOrderId());
        UpdateOperations<TicketOrderItemEntity> update = datastore.createUpdateOperations(TicketOrderItemEntity.class);
        update.set("updatedAt", System.currentTimeMillis());

        if(ticketOrderItemEntity.getOrderState() != null){
            update.set("orderState", ticketOrderItemEntity.getOrderState());
        }
        if(ticketOrderItemEntity.getPayState() != null){
            update.set("payState", ticketOrderItemEntity.getPayState());
        }
        if(ticketOrderItemEntity.getRefundAmount() != null){
            update.set("refundAmount", ticketOrderItemEntity.getRefundAmount());
        }
        if(ticketOrderItemEntity.getRefundTime() != null){
            update.set("refundTime", ticketOrderItemEntity.getRefundTime());
        }
        if(ticketOrderItemEntity.getSettleMoney() != null){
            update.set("settleMoney", ticketOrderItemEntity.getSettleMoney());
        }
        if(ticketOrderItemEntity.getUseTime() != null){
            update.set("useTime", ticketOrderItemEntity.getUseTime());
        }
        if(ticketOrderItemEntity.getSaleCountIndex() != null){
            update.set("saleCountIndex", ticketOrderItemEntity.getSaleCountIndex());
        }
        if(ticketOrderItemEntity.getSettleStatus() != null){
            update.set("settleStatus", ticketOrderItemEntity.getSettleStatus());
        }
        if(ticketOrderItemEntity.getSettleTime() != null){
            update.set("settleTime", ticketOrderItemEntity.getSettleTime());
        }
        if(ticketOrderItemEntity.getRefundSettleTime() != null){
            update.set("refundSettleTime", ticketOrderItemEntity.getRefundSettleTime());
        }
        if(ticketOrderItemEntity.getSettleType() != null){
            update.set("settleType", ticketOrderItemEntity.getSettleType());
        }
        if(ticketOrderItemEntity.getCreateTime() != null){
            update.set("createTime", ticketOrderItemEntity.getCreateTime());
        }

        UpdateResults updateResults = datastore.update(query, update);
        return updateResults.getUpdatedExisting();
    }

    @Override
    public List<TicketOrderItemEntity> getOrderItemList(String shopOrderId, String distributorId, String ticketId, Long minCreateTime, Long maxCreateTime,
                                                   Integer payState) {
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class)
                .field("settleTime").doesNotExist(); //结算时间不存在
        if(StringUtils.isNotBlank(shopOrderId)){
            query.filter("shopOrderId", shopOrderId);
        }
        if(StringUtils.isNotBlank(distributorId)){
            query.filter("distributorId", distributorId);
        }
        if(StringUtils.isNotBlank(ticketId)){
            query.filter("ticketId", ticketId);
        }
        if(payState != null){
            query.filter("payState", payState);
        }
        if(minCreateTime != null){
            query.filter("createTime >=", minCreateTime);
        }
        if(maxCreateTime != null){
            query.filter("createTime <", maxCreateTime);
        }
        return query.asList();
    }

    @Override
    public List<TicketOrderItemEntity> getUseOrderItemList(String shopOrderId, String distributorId, String ticketId, Long minUseTime, Long maxUseTime, Integer payState) {
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class)
                .field("settleTime").doesNotExist(); //结算时间不存在
        if(StringUtils.isNotBlank(shopOrderId)){
            query.filter("shopOrderId", shopOrderId);
        }
        if(StringUtils.isNotBlank(distributorId)){
            query.filter("distributorId", distributorId);
        }
        if(StringUtils.isNotBlank(ticketId)){
            query.filter("ticketId", ticketId);
        }
        if(payState != null){
            query.filter("payState", payState);
        }
        if (minUseTime != null){
            query.filter("useTime >=", minUseTime);
        }
        if(maxUseTime != null){
            query.filter("useTime <", maxUseTime);
        }
        return query.asList();
    }

    @Override
    public List<TicketOrderItemEntity> getRefundOrderItemList(String shopOrderId, String distributorId, String ticketId, Long minRefundTime, Long maxRefundTime, Integer payState) {
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class)
                .field("settleTime").exists()  //已结算
                .field("refundSettleTime").doesNotExist(); //退款未结算
        if(StringUtils.isNotBlank(shopOrderId)){
            query.filter("shopOrderId", shopOrderId);
        }
        if(StringUtils.isNotBlank(distributorId)){
            query.filter("distributorId", distributorId);
        }
        if(StringUtils.isNotBlank(ticketId)){
            query.filter("ticketId", ticketId);
        }
        if(payState != null){
            query.filter("payState", payState);
        }
        if(minRefundTime != null){
            query.filter("refundTime >=", minRefundTime);
        }
        if(maxRefundTime != null){
            query.filter("refundTime <", maxRefundTime);
        }
        return query.asList();
    }

    @Override
    public TicketOrderItemEntity getById(String id) {
        if(StringUtils.isBlank(id)){
            return null;
        }
        return datastore.createQuery(TicketOrderItemEntity.class).filter("_id", id).get();
    }

    @Override
    public List<TicketOrderItemEntity> getListByShopOrderId(String shopOrderId) {
        return datastore.createQuery(TicketOrderItemEntity.class)
                .filter("shopOrderId", shopOrderId).asList();
    }

    @Override
    public TicketOrderItemEntity getByTicketCode(String ticketCode) {
        return datastore.createQuery(TicketOrderItemEntity.class).filter("ticketCode", ticketCode).get();
    }

    @Override
    public long getUseOrderItemCountByOrderId(String shopOrderId) {
        return datastore.createQuery(TicketOrderItemEntity.class)
                .field("useTime").exists()
                .filter("shopOrderId", shopOrderId).count();
    }

    @Override
    public List<TicketOrderItemEntity> getList4SettleRecord(String shopId, String orderIdOrItemIdOrTicketCode, Long useBeginTIme, Long useEndTime, PagingVo pagingVo) {
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class)
                .field("useTime").exists();
        if(StringUtils.isNotBlank(shopId)){
            query.filter("shopId", shopId);
        }
        if(StringUtils.isNotBlank(orderIdOrItemIdOrTicketCode)){
            query.or(query.criteria("shopOrderId").equal(orderIdOrItemIdOrTicketCode),
                    query.criteria("ticketCode").equal(orderIdOrItemIdOrTicketCode),
                    query.criteria("_id").equal(orderIdOrItemIdOrTicketCode));
        }
        if(useBeginTIme != null){
            query.filter(" useTime >=", useBeginTIme);
        }
        if (useEndTime != null){
            query.filter(" useTime <=", useEndTime);
        }
        if(pagingVo != null){
            query.limit(pagingVo.getPs()).offset(pagingVo.getPageOffset());
        }
        return query.asList();
    }

    @Override
    public long getCount4SettleRecord(String shopId, String orderIdOrItemIdOrTicketCode, Long useBeginTIme, Long useEndTime) {
        Query<TicketOrderItemEntity> query = datastore.createQuery(TicketOrderItemEntity.class)
                .field("useTime").exists();
        if(StringUtils.isNotBlank(shopId)){
            query.filter("shopId", shopId);
        }
        if(StringUtils.isNotBlank(orderIdOrItemIdOrTicketCode)){
            query.or(query.criteria("shopOrderId").equal(orderIdOrItemIdOrTicketCode),
                    query.criteria("ticketCode").equal(orderIdOrItemIdOrTicketCode),
                    query.criteria("_id").equal(orderIdOrItemIdOrTicketCode));
        }
        if(useBeginTIme != null){
            query.filter("useTime >=", useBeginTIme);
        }
        if (useEndTime != null){
            query.filter("useTime <=", useEndTime);
        }
        return query.count();
    }
}
